<!DOCTYPE html>
<html>
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  <head>
<!--
Copyright 2009 Google Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
    <title>Custom Controls using Screen Overlays or IFRAME shims</title>
    <!-- *** Replace the key below below with your own API key, available at http://code.google.com/apis/maps/signup.html *** -->
    <script src="http://www.google.com/jsapi?key=ABQIAAAAwbkbZLyhsmTCWXbTcjbgbRSzHs7K5SvaUdm8ua-Xxy_-2dYwMxQMhnagaawTo7L1FE1-amhuQxIlXw"></script>
    <style type="text/css">
      /* CSS sprites */
      .tri-button {
        overflow: hidden;
      }
      
      .tri-button, .tri-button:visited {
        background: transparent none no-repeat scroll 0% 0%;
      }
      
      .tri-button:hover { background-position: 0% 50%; }
      .tri-button:active { background-position: 0% 100%; }
    </style>
    <script>
google.load("earth", "1");

var ge = null;

var appPath = document.location.href.replace(/\/[^\/]*$/, '/');

function init() {
  google.earth.createInstance("map3d", initCallback, failureCallback);
}

function initCallback(pluginInstance) {
  ge = pluginInstance;
  ge.getWindow().setVisibility(true);
  
  // create the buttons
  createNativeHTMLButton(100, 100, 210, 40); // x, y, width, height
  createScreenOverlayButton(100, 200, 210, 40); // x, y, width, height
}

function failureCallback(object) {
}

/**
 * Helper function for element.addEventListener/attachEvent
 */
function addDomListener(element, eventName, listener) {
  if (element.addEventListener)
    element.addEventListener(eventName, listener, false);
  else if (element.attachEvent)
    element.attachEvent('on' + eventName, listener);
}

/**
 * Helper function to get the rectangle for the given HTML element.
 */
function getElementRect(element) {
  var left = element.offsetLeft;
  var top = element.offsetTop;
  
  var p = element.offsetParent;
  while (p && p != document.body.parentNode) {
    if (isFinite(p.offsetLeft) && isFinite(p.offsetTop)) {
      left += p.offsetLeft;
      top += p.offsetTop;
    }
    
    p = p.offsetParent;
  }
  
  return { left: left, top: top,
           width: element.offsetWidth, height: element.offsetHeight };
}

/**
 * Create a custom button using the IFRAME shim and CSS sprite technique
 * at the given x, y offset from the top left of the plugin container.
 */
function createNativeHTMLButton(x, y, width, height) {
  // create the button
  var button = document.createElement('a');
  button.href = '#';
  button.className = 'tri-button';
  button.style.display = 'block';
  button.style.backgroundImage = 'url(btn_html.png)';
  button.style.backgroundColor = 'white';
  
  // create an IFRAME shim for the button
  var iframeShim = document.createElement('iframe');
  iframeShim.frameBorder = 0;
  iframeShim.scrolling = 'no';
  iframeShim.src = (navigator.userAgent.indexOf('MSIE 6') >= 0) ?
      '' : 'javascript:void(0);';

  // position the button and IFRAME shim
  var pluginRect = getElementRect(document.getElementById('map3d'));
  button.style.position = iframeShim.style.position = 'absolute';
  button.style.left = iframeShim.style.left = (pluginRect.left + x) + 'px';
  button.style.top = iframeShim.style.top = (pluginRect.top + y) + 'px';
  button.style.width = iframeShim.style.width = width + 'px';
  button.style.height = iframeShim.style.height = height + 'px';
  
  // set up z-orders
  button.style.zIndex = 10;
  iframeShim.style.zIndex = button.style.zIndex - 1;
  
  // set up click handler
  addDomListener(button, 'click', function(evt) {
    alert('You clicked the native HTML button!');
    
    if (evt.preventDefault) {
      evt.preventDefault();
      evt.stopPropagation();
    }
    return false;
  });
  
  // add the iframe shim and button
  document.body.appendChild(button);
  document.body.appendChild(iframeShim);
}

/**
 * Create a custom button using screen overlays
 * at the given x, y offset from the top left of the plugin container.
 */
function createScreenOverlayButton(x, y, width, height) {
  var _addOverlayForState = function(suffix, drawOrder, visible) {
    // Create the loading overlay.
    var icon = ge.createIcon('');
    icon.setHref(appPath + 'btn_so' + suffix + '.png');

    var overlay = ge.createScreenOverlay('');
    overlay.setDrawOrder(drawOrder || 0);
    overlay.setVisibility(visible || false);
    overlay.setIcon(icon);
    overlay.getOverlayXY().set(x, ge.UNITS_PIXELS, y, ge.UNITS_INSET_PIXELS);
    overlay.getScreenXY().set(0, ge.UNITS_FRACTION, 1, ge.UNITS_FRACTION);
    overlay.getSize().set(width, ge.UNITS_PIXELS, height, ge.UNITS_PIXELS);
    ge.getFeatures().appendChild(overlay);
    
    return overlay;
  };
  
  var overlayReg = _addOverlayForState('', 1, true);
  var overlayHover = _addOverlayForState('_hover', 2, false);
  var overlayDown = _addOverlayForState('_down', 3, false);
  
  var _setState = function(state) {
    overlayHover.setVisibility(state == 'hover');
    overlayDown.setVisibility(state == 'down');
  };
  
  // NOTE: if you have many screen overlay controls, you should collapse
  // this code down to one listener per event to handle all controls.
  
  var _isMouseOnButton = function(mx, my) {
    return x <= mx && mx <= x + width &&
           y <= my && my <= y + height;
  };
  
  var buttonDown = false;
  
  google.earth.addEventListener(ge.getWindow(), 'mousedown', function(evt) {
    if (evt.getButton() != 0) // left click
      return;
    
    if (_isMouseOnButton(evt.getClientX(), evt.getClientY())) {
      buttonDown = true;
      _setState('down');
      event.preventDefault();
      return false;
    }
  });
  
  google.earth.addEventListener(ge.getWindow(), 'mousemove', function(evt) {
    if (_isMouseOnButton(evt.getClientX(), evt.getClientY())) {
      _setState(buttonDown ? 'down' : 'hover');
    } else {
      _setState(buttonDown ? 'hover' : '');
    }
    
    if (buttonDown) {
      event.preventDefault();
      return false;
    }
  });
  
  google.earth.addEventListener(ge.getWindow(), 'mouseup', function(evt) {
    if (buttonDown) {
      buttonDown = false;
      _setState(_isMouseOnButton(evt.getClientX(), evt.getClientY()) ?
          'hover' : '');
      event.preventDefault();
      return false;
    }
  });
  
  google.earth.addEventListener(ge.getWindow(), 'click', function(evt) {
    if (evt.getButton() === 0 &&
        _isMouseOnButton(evt.getClientX(), evt.getClientY())) {
      alert('You clicked the screen overlay button!');
      buttonDown = false;
    }
  });
}
    </script>
  </head>
  <body onload='init()' id='body'>
      <div>
        Custom Controls using Screen Overlays or <code>IFRAME</code> shims
      </div>

      <div id="map3d" style="height: 600px; width: 800px;"></div>
  </body>
</html>
